home *** CD-ROM | disk | FTP | other *** search
- static char *rcsid = "$Id: man.c,v 1.4 1992/10/12 09:59:02 rosenkra Exp $";
- static char *version = "man v3.0.2 92/10/11 rosenkra@convex.com";
- static char *myname = "man";
-
- /*
- * man - read on-line documentation
- *
- * This version uses "manpager" or "less" for paging. It does NOT
- * call nroff (ie, manpages must be preformatted -- see SUBDIRBASE
- * macro below).
- *
- * search order (based on my manpage nomenclature):
- *
- * man1/*.1[tcgesla] cmds util & text,com,graphics,
- * edit,shell,lang, archival
- * man0/*.0 gen
- * man8/*.8[s] admin util & system
- * man2/*.2[b] syslib system & bios
- * man3/*.3[msvcxl] libs C lib & math,stdio,sysV,
- * compat,extra,local
- * man4/*.4[dkvscm] h/w gen & disk,keyboard,video,
- * sound,chips,memory
- * man5/*.5 files
- * man7/*.7 misc
- * man6/*.6 games
- *
- * these are seached only if given sections "local", "new", "old":
- *
- * manl/*.l local
- * mann/*.n new
- * mano/*.o old
- */
-
- /*
- * $Log: man.c,v $
- * Revision 1.4 1992/10/12 09:59:02 rosenkra
- * basically same as last version (which was premature). fix a couple
- * of bugs.
- *
- * Revision 1.3 1992/10/11 16:21:24 rosenkra
- * this is v3.0.2. it adds a -P alias for -M, ability to source files
- * with either .so manx/file.x or .so file.x; also added was MANSECT
- * env var. help (usage) was beefed up. all reading of env now done in
- * env_inquiry().
- *
- * Revision 1.2 1992/07/27 10:03:38 rosenkra
- * added ability to review all manpages of given name regardless
- * of section (-e). also do env checks before arg parsing.
- *
- * Revision 1.1 1992/07/27 02:03:58 rosenkra
- * Initial revision
- *
- */
-
-
-
- #ifdef __hpux
- /* HPUX for some reason needs this with <sys/stat.h> */
- #define _INCLUDE_POSIX_SOURCE 1
- #define unix 1
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
- #if defined(unix) || defined(__unix)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #elif defined(__GNUC__) && defined(MSDOS)
- #include <types.h>
- #include <stat.h>
- #include <stdlib.h>
- #include <unistd.h>
- #else
- #include <sys\types.h>
- #include <sys\stat.h>
- extern char *index ();
- extern char *getenv ();
- #endif
- #ifdef USE_INDEX
- #include <strings.h>
- #define strchr index
- #define strrchr rindex
- #endif
-
-
- /*
- * deal with MSDOS
- */
- #if defined(unix) || defined(__unix)
- #define SLASH_CHR '/'
- #define SLASH_STR "/"
- #else
- #define SLASH_CHR '\\'
- #define SLASH_STR "\\"
- #endif
-
-
-
- /*
- * common (default) places. note the patch space...
- */
- #if defined(atarist) || defined(MSDOS)
- # define MANDIR "c:\\usr\\man\0\0\0<------MANDIR_patch_space------->\0"
- # define BINDIR "c:\\usr\\bin\0\0\0<------BINDIR_patch_space------->\0"
- # define TMPDIR "c:\\tmp\0\0\0<---------TMPDIR_patch_space--------->\0"
- #else
- /* assume unix */
- # define MANDIR "/usr/man"
- # define BINDIR "/usr/bin"
- # define TMPDIR "/tmp"
- #endif
-
-
-
- /*
- * default pager (we invoke this with system()):
- */
- #if defined(unix) || defined(__unix)
- # define MORE "less" /* could use -m -s also */
- #elif defined(atarist)
- # define MORE "less.ttp\0\0\0<--------MORE_patch_space----------->\0"
- #elif defined(MSDOS)
- # define MORE "less.exe\0\0\0<--------MORE_patch_space----------->\0"
- #endif
-
-
- /*
- * other commands we may run
- */
- #ifdef HAS_CAT
- # if defined(unix) || defined(__unix)
- # define CAT "cat -s" /* for '-' opt, use "cat -s" */
- # elif defined(atarist)
- # define CAT "cat.ttp\0\0\0<---------CAT_patch_space------------>\0"
- # elif defined(MSDOS)
- # define CAT "cat.exe\0\0\0<---------CAT_patch_space------------>\0"
- # else
- # undef HAS_CAT
- # endif
- #endif
-
- #ifdef HAS_UL
- # if defined(unix) || defined(__unix)
- # define UL "ul -t dumb" /* for '- -ul' opt (don't use pager) */
- # elif defined(atarist)
- # define UL "ul.ttp\0\0\0<----------UL_patch_space------------->\0"
- # elif defined(MSDOS)
- # define UL "ul.exe\0\0\0<----------UL_patch_space------------->\0"
- # else
- # undef HAS_UL
- # endif
- #endif
-
- #ifdef HAS_APROPOS
- # if defined(unix) || defined(__unix)
- # define APROPOS "apropos"
- # elif defined(atarist)
- # define APROPOS "apropos.ttp\0\0<--------APROPOS_patch_space------->\0"
- # elif defined(MSDOS)
- # define APROPOS "apropos.exe\0\0<--------APROPOS_patch_space------->\0"
- # else
- # undef HAS_APROPOS
- # endif
- #endif
-
- #ifdef HAS_WHATIS
- # if defined(unix) || defined(__unix)
- # define WHATIS "whatis"
- # elif defined(atarist)
- # define WHATIS "whatis.ttp\0\0<--------WHATIS_patch_space--------->\0"
- # elif defined(MSDOS)
- # define WHATIS "whatis.ttp\0\0<--------WHATIS_patch_space--------->\0"
- # else
- # undef HAS_WHATIS
- # endif
- #endif
-
-
- /*
- * define sections and subsections. sections are dirs like "man1" and
- * "cat1". subsections are used in names of manpages within the dir
- * (eg, "foo.1t").
- */
- #define ALLSECT "108234576" /* order to look through sections */
-
- #define SUBSEC0 "" /* subsec to try in each section */
- #define SUBSEC1 "tcgesla"
- #define SUBSEC2 "g"
- #define SUBSEC3 "msvcxl"
- #define SUBSEC4 "dkvscm"
- #define SUBSEC5 ""
- #define SUBSEC6 ""
- #define SUBSEC7 ""
- #define SUBSEC8 "s"
- #define SUBSEC9 ""
-
- /*
- * deal with compressed files
- */
- #if defined(MSDOS)
- #define ZSUFFIX "Z" /* for compressed files */
- #else
- #define ZSUFFIX ".Z" /* for compressed files */
- #endif
- #define ZSWITCH "-z" /* for MANPAGER to read compressed file */
-
-
- /*
- * files come from MANPATH/cat*. normally, unix man will first
- * check for preformatted manpages in /usr/man/cat* dirs. if they
- * are not found, nroff is run on /usr/man/man* files. with this
- * man, however, we are assuming that manpages have already been
- * formatted. by convention, this means that the dirs to search
- * should be named 'cat[1-8]' and not 'man[1-8]'. if you don't
- * care about this, make SUBDIRBASE "man".
- */
- #define SUBDIRBASE "cat"
-
-
-
- #ifdef dbg
- # undef dbg
- #endif
- #define dbg(x) if(debugging_G)printf x , fflush(stdout)
-
-
- /*
- * misc macros
- */
- #ifdef lastchar
- # undef lastchar
- #endif
- #ifdef plastchar
- # undef plastchar
- #endif
- #define lastchar(s) ((s)[strlen(s)-1]) /* last char in a string */
- #define plastchar(s) &((s)[strlen(s)-1]) /* ptr to it */
-
-
- #define PLEN 256 /* max path length */
-
-
-
-
- /*
- * globals:
- */
- #ifdef HAS_UL
- int ul4cat_G = 0; /* use ul instead of cat */
- #endif
- int every_G = 0; /* every section */
- int debugging_G = 0;
- int hasmanpager_G = 0; /* if pager is MANPAGER */
- int usermanpath_G = 0; /* if -M */
- int nopager_G = 0; /* if no pager of any kind */
- int pthpager_G = 0; /* if pager has a full path */
- int envmansect_G = 0; /* if MANSECT in env */
- char *manpath_G = 0L;
- char mpbuf[PLEN];
- char *binpath_G = 0L;
- char bpbuf[PLEN];
- char *tmppath_G = 0L;
- char tpbuf[PLEN];
- char *pager_G = 0L;
- char pgbuf[PLEN];
- char cmdbuf_G[512];
- int section_G = 0; /* section, ascii char */
- int subsec_G = 0; /* subsection, ascii char */
-
-
- /*
- * set up default search lists. these can be overridden with the env:
- *
- * setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,
- */
- char *allsect = ALLSECT;
- char *subsec0 = SUBSEC0;
- char *subsec1 = SUBSEC1;
- char *subsec2 = SUBSEC2;
- char *subsec3 = SUBSEC3;
- char *subsec4 = SUBSEC4;
- char *subsec5 = SUBSEC5;
- char *subsec6 = SUBSEC6;
- char *subsec7 = SUBSEC7;
- char *subsec8 = SUBSEC8;
- char *subsec9 = SUBSEC9;
-
- #ifdef LONG_SECT
- char *longsect[] = {"local", "new", "old", "gnu", "paper",
- "doc", (char *) 0};
- #endif
-
-
-
- /*
- * functions:
- */
- int set_section (char *);
- int find_manpage (char *);
- int do_it (char *, int);
- char *so_line (char *);
- void env_inquiry (void);
- void usage (int);
-
-
-
- /*------------------------------*/
- /* main */
- /*------------------------------*/
- void main (int argc, char *argv[])
- {
- int retcode;
- char **av;
- int ac;
-
-
-
- /*
- * quick scan of args to find debug since we need it first.
- * note that argc and argv are not changed...
- */
- ac = argc;
- av = argv;
- for (ac--, av++; ac > 0 && **av == '-'; ac--, av++)
- {
- if (*(*av+1) == 'd')
- {
- debugging_G = 1;
- break;
- }
- }
-
-
-
-
- /*
- * check environment (cmdline overrules things)
- */
- env_inquiry ();
-
-
-
- /*
- * must have an arg
- */
- argc--, argv++;
- if (argc < 1)
- {
- usage (1);
- }
-
-
-
- /*
- * parse cmdline. it overrides defaults and environment...
- */
- while (argc > 0 && **argv == '-')
- {
- switch (*(*argv+1))
- {
-
- case 0: /* use cat (just a "-") */
- #ifdef HAS_CAT
- nopager_G++;
- #else
- fprintf (stderr, "%s: cat and not supported\n");
- usage (1);
- #endif
- break;
-
-
- case 'e': /* every section */
- every_G++;
- break;
-
-
- case 'P':
- case 'M': /* reset path (-M path) */
- /* this is manpath/man[1...] */
- argc--, argv++;
- manpath_G = *argv;
- break;
-
-
- case 'm': /* reset path (-m path) */
- /* this is manpath alone */
- /* use "-m ." for cwd */
- argc--, argv++;
- manpath_G = *argv;
- usermanpath_G = 1;
- break;
-
-
- case 'u': /* use ul(1) for cat */
- #ifdef HAS_UL
- ul4cat_G++;
- #else
- fprintf (stderr, "%s: ul not supported\n");
- usage (1);
- #endif
- break;
-
-
- case 's': /* specific section */
- switch (--argc)
- {
- case 0: /* Nothing follows -s */
- fprintf (stderr,
- "%s: must specify a section with -s\n",
- myname);
- usage (1);
-
- case 1: /* Section, but no man page */
- fprintf (stderr,
- "%s: must specify an item from section %s\n",
- myname, *argv);
- usage (1);
-
- default:
- /*
- * if valid section, set_section sets
- * section_G
- */
- if (set_section (*++argv) == 0)
- {
- fprintf (stderr,
- "%s: unknown section: %s\n",
- myname, *argv);
- usage (1);
- }
- break;
- }
- break;
-
-
- case 'f': /* whatis */
- case 'w':
- #ifdef HAS_WHATIS
- #if defined(__GNUC__) || defined(unix) || defined(__unix)
- strcpy (cmdbuf_G, WHATIS);
- #else
- strcpy (cmdbuf_G, binpath_G);
- if (lastchar (cmdbuf_G) != SLASH_CHR)
- strcat (cmdbuf_G, SLASH_STR);
- strcat (cmdbuf_G, WHATIS);
- #endif /*__GNUC__*/
- argc--, argv++;
- while (argc)
- {
- strcat (cmdbuf_G, " ");
- strcat (cmdbuf_G, *argv);
- argc--, argv++;
- }
- dbg(("whatis, system (%s)\n",cmdbuf_G));
- retcode = system (cmdbuf_G);
-
- exit (retcode);
- #else /*!HAS_WHATIS*/
- fprintf (stderr, "%s: whatis not supported\n");
- usage (1);
- #endif /*HAS_WHATIS*/
- break;
-
-
- case 'k': /* apropos */
- case 'a':
- #ifdef HAS_APROPOS
- strcpy (cmdbuf_G, APROPOS);
- #if defined(__GNUC__) || defined(unix) || defined(__unix)
- strcpy (cmdbuf_G, APROPOS);
- #else
- strcpy (cmdbuf_G, binpath_G);
- if (lastchar (cmdbuf_G) != SLASH_CHR)
- strcat (cmdbuf_G, SLASH_STR);
- strcat (cmdbuf_G, APROPOS);
- #endif /*__GNUC__*/
- argc--, argv++;
- while (argc)
- {
- strcat (cmdbuf_G, " ");
- strcat (cmdbuf_G, *argv);
- argc--, argv++;
- }
- dbg(("apropos, system (%s)\n",cmdbuf_G));
- retcode = system (cmdbuf_G);
-
- exit (retcode);
- #else /*!HAS_APROPOS*/
- fprintf (stderr, "%s: apropos not supported\n");
- usage (1);
- #endif /*HAS_APROPOS*/
- break;
-
-
- case 'h': /* help */
- usage (0);
- break;
-
-
- case 'd': /* turn on debugging */
- debugging_G = 1;
- break;
-
-
- case 'v': /* version */
- printf ("%s\n", version);
- exit (0);
- break;
-
- case '-':
- switch (*(*argv+2))
- {
- case 'v': /* --version */
- printf ("%s\n", version);
- exit (0);
- break;
-
- case 'h': /* --help */
- usage (0);
- break;
- }
- break;
-
-
- }
- argc--, argv++;
- }
-
-
-
-
- /*
- * If there are multiple words, no -s seen above, and the first
- * word is a valid section name, read the subsequent man pages
- * from that section. set_section will set section_G if *argv is a
- * bona fide section.
- *
- * this also should make sure arg is a digit and only <sect>[<sub>]
- * but will fail on actual manpages named something like "1.1".
- * hopefully these are non-existent.
- */
- if ((argc > 1) && (section_G == 0)
- && (set_section (*argv) || (isdigit(**argv) && (strlen(*argv) < 3))))
- {
- argc--;
- argv++;
- }
-
-
-
- /*
- * move to correct directory. no need to move if it is cwd...
- */
- if (strcmp (manpath_G, ".") && (chdir (manpath_G) < 0))
- {
- fprintf (stderr, "%s: can't chdir to %s.\n",
- myname, manpath_G);
- exit (1);
- }
-
-
-
- /*
- * check if stdout not a tty an no pager.
- */
- #if 0
- if (nopager_G == 0 && !isatty (1))
- nopager_G++;
- #endif
- dbg(("nopager_G = %d, isatty(1) = %d\n", nopager_G, (int) isatty(1)));
-
-
-
- /*
- * do it for all remaining tokens
- */
- while (argc-- > 0)
- {
- retcode = find_manpage (*argv++);
-
- if (retcode)
- {
- fprintf (stderr, "%s: failed!!!\n", myname);
- exit (retcode);
- }
- }
-
- exit (0);
- }
-
-
-
-
- /*------------------------------*/
- /* set_section */
- /*------------------------------*/
- int set_section (char *cptr)
- {
-
- /*
- * routine to set section_G and subsec_G from a given section name,
- * returning the letter of the section used or a zero if an unfamiliar
- * keyword is used.
- */
-
- int sec;
- int ret;
- int i;
-
- if (strlen (cptr) > 2)
- {
- /*
- * section is 3 or more char
- */
- #ifdef LONG_SECT
- for (i = 0; longsect[i]; i++)
- {
- if (!strcmp (longsect[i], cptr))
- return (section_G = (int) (*longsect[i]));
- }
- #else
- if (!strcmp (cptr, "local"))
- return ((int) (section_G = 'l'));
- if (!strcmp (cptr, "new"))
- return ((int) (section_G = 'n'));
- if (!strcmp (cptr, "old"))
- return ((int) (section_G = 'o'));
- #endif
-
- /*
- * If we reach here, none of the special names match,
- * and we'll return a zero (error) on the other side of
- * the else.
- */
- section_G = '\0';
- subsec_G = '\0';
- ret = 0;
- }
- else
- {
- /*
- * section is 2 or less char. subsec could be 0
- */
- section_G = (int) cptr[0];
- subsec_G = (int) cptr[1];
- ret = section_G;
-
-
- /*
- * crude check for legality: section must be 0-8, subsect
- * must be a letter
- */
- sec = section_G - '0';
- /*!!!*/ if (sec < 0 || sec > 9)
- ret = 0;
- if (subsec_G)
- {
- if (!isalpha (subsec_G))
- ret = 0;
- }
- }
-
- /*
- * ret is 0 if invalid section, else section number
- */
- return (ret);
- }
-
-
-
- struct stat sbuf;
-
-
- /*------------------------------*/
- /* find_manpage */
- /*------------------------------*/
- int find_manpage (char *name)
- {
-
- /*
- * find the manpage file
- */
-
- char c_sectn;
- char work[PLEN];
- int stflag;
- int last;
- char seclist[30];
- char sublist[30];
- char *psec;
- char *psub;
- char *ps;
- char *cp;
- int iscompressed = 0;
- int found = 0;
-
-
-
- /*
- * set up template (we removed any trailing '/' already)
- *
- * if usermanpath is set, we read from that dir and don't assume
- * any "normal" dir structure (-m option). otherwise we do normal
- * (or -M option).
- */
- if (usermanpath_G)
- sprintf (work, "%s%s%s.x", manpath_G, SLASH_STR, name);
- else
- sprintf (work, "%s%s%sx%s%s.x",
- manpath_G, SLASH_STR, SUBDIRBASE, SLASH_STR, name);
-
-
-
- /*
- * index of last char in template. this should be section.
- * work[last+1] is subsection, and work[last+2] will be ZSUFFIX
- * if compressed and we are using MANPAGER.
- */
- last = strlen (work) - 1;
- dbg(("template, work = |%s|, last = %d\n", work, last));
-
-
-
- /*
- * set up list of sections to search. either use section_G or
- * allsect
- */
- if (section_G)
- {
- seclist[0] = (char) section_G;
- seclist[1] = '\0';
- }
- else
- {
- strcpy (seclist, allsect);
- }
- psec = seclist;
- if (subsec_G)
- {
- sublist[0] = (char) subsec_G;
- sublist[1] = '\0';
- psub = sublist;
- }
- else
- psub = (char *) NULL;
- dbg(("psec = |%s|, psub = |%s|\n", psec, (psub ? psub : "NULL")));
-
-
-
- /*
- * find manx string in template. ps points to the '/'
- */
- if (!usermanpath_G)
- {
- char tmpstringx[PLEN];
- tmpstringx[0] = SLASH_CHR;
- strcpy(&tmpstringx[1], SUBDIRBASE);
- for (ps = work; *ps; ps++)
- {
- if (!strncmp (ps, tmpstringx, 4)
- && *(ps+5) == SLASH_CHR)
- break;
- }
- }
-
-
-
- /*
- * loop thru all sections. could be only specified section
- */
- for (c_sectn = *psec; c_sectn; c_sectn = *++psec)
- {
- /*
- * fill in template: man_/xxx._\0\0 (no sub yet)
- */
- if (!usermanpath_G)
- ps[4] = c_sectn;
-
- work[last] = c_sectn;
- work[last + 1] = 0;
- work[last + 2] = 0;
- work[last + 3] = 0;
-
-
- /*
- * if a subsection was specified, skip past this...
- */
- if (subsec_G)
- goto SEARCH;
-
-
- /*
- * does this file exist?
- */
- dbg(("try |%s|...\n", work));
- if ((stflag = stat (work, &sbuf)) >= 0)
- {
- /*
- * yes...exit this for loop
- */
- if (every_G)
- {
- /*
- * PAGER should support ^C exit. it should
- * exit with status 1 in that case (and
- * do_it() would also return 1). it is not
- * an error, however, to exit this way but
- * we return (with 0) so next item will
- * be searched.
- */
- found++;
- if (do_it (work, iscompressed))
- return (0);
- goto NEXT_LOOP;
- }
- else
- goto FOUND_ONE;
- }
-
-
- /*
- * no...try looking for compressed version
- */
- if (hasmanpager_G)
- {
- dbg(("not found, try compressed file...\n"));
-
- #if 0
- work[last + 1] = ZSUFFIX;
- work[last + 2] = '\0';
- work[last + 3] = '\0';
- #endif
- strcpy(&work[last+1], ZSUFFIX);
-
- dbg(("try |%s|...\n", work));
- if ((stflag = stat (work, &sbuf)) >= 0)
- {
- /*
- * yes...
- */
- iscompressed = 1;
-
- if (every_G)
- {
- found++;
- if (do_it (work, iscompressed))
- return (0);
- goto NEXT_LOOP;
- }
- else
- goto FOUND_ONE;
- }
- work[last + 1] = '\0'; /* reset! */
-
- dbg(("not found...\n"));
- }
-
-
- SEARCH: ;
- /*
- * still not found...look for subsections in manx
- *
- * set up subsect string
- */
- if (subsec_G)
- cp = psub;
- else
- {
- /*
- * take the default subsections for a section...
- */
- switch (work[last])
- {
- case '0': cp = subsec0; break;
- case '1': cp = subsec1; break;
- case '2': cp = subsec2; break;
- case '3': cp = subsec3; break;
- case '4': cp = subsec4; break;
- case '5': cp = subsec5; break;
- case '6': cp = subsec6; break;
- case '7': cp = subsec7; break;
- case '8': cp = subsec8; break;
- case '9': cp = subsec9; break;
- default: cp = ""; break;
- }
- }
- dbg(("not found, try subsect, cp = |%s|\n", cp));
-
-
- /*
- * cycle thru subsections
- */
- while (*cp)
- {
- /*
- * do we find one now?
- */
- work[last + 1] = *cp++;
- work[last + 2] = '\0';
- dbg(("try |%s|...\n", work));
- if ((stflag = stat (work, &sbuf)) >= 0)
- {
- /*
- * yes...
- */
- if (every_G)
- {
- found++;
- if (do_it (work, iscompressed))
- return (0);
- goto NEXT_LOOP;
- }
- else
- goto FOUND_ONE;
- }
-
-
- /*
- * still no...try compressed...
- */
- if (hasmanpager_G)
- {
- dbg(("not found, try compressed file...\n"));
-
- #if 0
- work[last + 2] = ZSUFFIX;
- work[last + 3] = '\0';
- #endif
- strcpy(&work[last+2], ZSUFFIX);
-
- dbg(("try |%s|...\n", work));
- if ((stflag = stat (work, &sbuf)) >= 0)
- {
- /*
- * yes...
- */
- iscompressed = 1;
- if (every_G)
- {
- found++;
- if (do_it (work, iscompressed))
- return (0);
- goto NEXT_LOOP;
- }
- else
- goto FOUND_ONE;
- }
- work[last + 2] = '\0'; /* reset! */
-
- dbg(("not found...\n"));
- }
- /* we give up. try next subsection, if any... */
- }
- /* we give up. try next section, if any... */
-
- NEXT_LOOP: ;
- }
-
- if (every_G)
- {
- if (found)
- return (0);
- else
- printf ("%s: no manual entry for %s. try man local %s\n",
- myname, name, name);
- }
- else
- {
- if (section_G == 0)
- printf ("%s: no manual entry for %s. try man local %s\n",
- myname, name, name);
- else
- printf ("%s: no entry for %s in section %c%c of the manual.\n",
- myname, name,
- (char) section_G,
- (subsec_G ? (char) subsec_G : ' '));
- }
- return (1);
-
-
- FOUND_ONE: ;
-
- dbg(("Found: %s(%x), iscompressed = %d\n",work,stflag,iscompressed));
-
- return ((int) do_it (work, iscompressed));
- }
-
-
-
-
- /*------------------------------*/
- /* do_it */
- /*------------------------------*/
- int do_it (char *cp, int iscompressed)
- {
- char cmdpath[256];
- char cmd[256];
- char *so;
-
-
-
-
- /*
- * open the file, look for ".so file" as first line. use that file
- * instead. only one level of this nesting is possible (the
- * included file can't include, too). do this only if file not
- * compressed!
- */
- dbg(("enter do_it, cp = |%s|...\n", cp));
- if (!iscompressed)
- {
- so = so_line (cp);
- if (so)
- {
- cp = so;
- dbg(("so_line found something, new cp = |%s|...\n",cp));
- }
- }
-
-
- /*
- * set up command path (for paging)
- */
- #if defined(__GNUC__) || defined(unix) || defined(__unix)
- cmdpath[0] = '\0';
- #else
- strcpy (cmdpath, binpath_G);
- if (lastchar (cmdpath) != SLASH_CHR)
- strcat (cmdpath, SLASH_STR);
- #endif
- if (!nopager_G)
- {
- /*
- * use pager. if compressed, add correct switch (note:
- * iscompressed set only if hasmanpager is true)
- */
- if (iscompressed)
- {
- sprintf (cmd, "%s%s %s %s",
- (pthpager_G ? "" : cmdpath),
- pager_G,
- ZSWITCH,
- cp);
- }
- else
- {
- sprintf (cmd, "%s%s %s",
- (pthpager_G ? "" : cmdpath),
- pager_G,
- cp);
- }
- }
- #ifdef HAS_UL
- else if (ul4cat_G)
- {
- /*
- * use ul rather than cat if no pager
- */
- sprintf (cmd, "%s%s %s", cmdpath, UL, cp);
- }
- #endif
- #ifdef HAS_CAT
- else
- {
- /*
- * use cat if no pager
- */
- sprintf (cmd, "%s%s %s", cmdpath, CAT, cp);
- }
- #endif
-
- /*
- * invoke the pager (or cat or ul)
- */
- dbg(("system (%s)\n", cmd));
-
- return ((int) system (cmd));
- }
-
-
-
-
- /*------------------------------*/
- /* so_line */
- /*------------------------------*/
- char *so_line (char *fname)
- {
-
- /*
- * read first line from found file, looking for ".so " followed by
- * alternate sourced file. if found, returns ptr to the new name.
- * otherwise, null.
- *
- * the file name should include the path of the subsection, e.g.
- * the file for degas.5 (in man5) contains:
- *
- * .so man5/picture.5
- *
- * the rest of the file (man5/degas.5) is ignored.
- *
- * new: now can also handle
- *
- * .so picture.5
- *
- * fname comes in with man5/degas.5 so use the leading path.
- */
-
- static char buf[256];
- char tbuf[256];
- char *so;
- FILE *stream;
- char *ps;
-
- so = (char *) 0;
-
- if ((stream = fopen (fname, "r")) == (FILE *) 0)
- {
- printf ("%s: could not open %s to look for .so\n",
- myname, fname);
- return (so);
- }
-
- /*
- * grab first line, delete newline
- */
- fgets (buf, 255, stream);
- fclose (stream);
- so = buf;
- while (*++so)
- ;
- *--so = '\0';
-
- /*
- * is it .so?
- */
- so = buf;
- if (!strncmp (so, ".so ", 4))
- {
- so += 4;
- while (*so == ' ' || *so == '\t')
- so++;
- dbg(("so_line read |%s|\n", so));
-
- if ((ps = strrchr (so, '\\')) == (char *) 0
- && (ps = strrchr (so, '/')) == (char *) 0)
- {
- /*
- * the .so line does not contain manx/name.x so
- * use path from fname.
- */
- strcpy (tbuf, so);
- strcpy (so, fname);
- if (ps = strrchr (so, SLASH_CHR))
- {
- ps++;
- strcpy (ps, tbuf);
- }
- else if (ps = strrchr (so, '/'))
- {
- ps++;
- strcpy (ps, tbuf);
- }
- }
-
- dbg(("so_line returning |%s|\n", so));
- return (so);
- }
- else
- {
- dbg(("so_line returning NULL\n"));
-
- return ((char *) 0);
- }
- }
-
-
-
- /*------------------------------*/
- /* env_inquiry */
- /*------------------------------*/
- void env_inquiry (void)
- {
-
- /*
- * look up things in environment:
- *
- * MANPAGER,PAGER
- * TEMP,TMPDIR
- * MANPATH,MANDIR
- * BINDIR
- * MANSECT
- *
- * setenv MANSECT 108234576
- * setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,
- */
- char *ps;
- char *pl;
- char *pd;
- static char sectbuf[256];
-
-
-
- /*
- * alternate pager from environment. if env has variable MANPAGER
- * defined, use it as pager (this allows dealing with bold and
- * italics in manpage, for example). if not, look for PAGER. if
- * neither is set, use default as defined by macro MORE here.
- */
- if (pager_G == (char *) NULL)
- {
- if ((ps = getenv ("MANPAGER")) != (char *) NULL)
- {
- strcpy (pgbuf, ps);
- pager_G = pgbuf;
- hasmanpager_G = 1;
- }
- else if ((ps = getenv ("PAGER")) != (char *) NULL)
- {
- strcpy (pgbuf, ps);
- pager_G = pgbuf;
- }
- else
- pager_G = MORE;
- }
- if (pager_G && (strchr (pager_G, ':') || strchr (pager_G, SLASH_CHR)))
- pthpager_G = 1;
- dbg(("pager_G = |%s|, pthpager_G = %d\n",(pager_G ? pager_G : "NULL"), pthpager_G));
-
-
-
-
- /*
- * place to put temp files, if needed (not needed yet...)
- */
- if (tmppath_G == (char *) NULL)
- {
- if ((ps = getenv ("TEMP")) != (char *) NULL)
- {
- strcpy (tpbuf, ps);
- tmppath_G = tpbuf;
- }
- else if ((ps = getenv ("TMPDIR")) != (char *) NULL)
- {
- strcpy (tpbuf, ps);
- tmppath_G = tpbuf;
- }
- else
- tmppath_G = TMPDIR;
- }
- if (tmppath_G && lastchar (tmppath_G) == SLASH_CHR)/* rem trail '/' */
- lastchar (tmppath_G) = '\0';
- dbg(("tmppath_G = |%s|\n", tmppath_G ? tmppath_G : "NULL"));
-
-
-
-
- /*
- * where man pages are (e.g. /usr/man)
- */
- if (manpath_G == (char *) NULL)
- {
- if ((ps = getenv ("MANPATH")) != (char *) NULL)
- {
- strcpy (mpbuf, ps);
- manpath_G = mpbuf;
- }
- else if ((ps = getenv ("MANDIR")) != (char *) NULL)
- {
- strcpy (mpbuf, ps);
- manpath_G = mpbuf;
- }
- else
- manpath_G = MANDIR;
- }
- if (manpath_G && lastchar (manpath_G) == SLASH_CHR)/* rem trail '/' */
- lastchar (manpath_G) = '\0';
- dbg(("manpath_G = |%s|\n", manpath_G ? manpath_G : "NULL"));
-
-
-
-
- /*
- * place to find pagers
- */
- if (binpath_G == (char *) NULL)
- {
- if ((ps = getenv ("BINDIR")) != (char *) NULL)
- {
- strcpy (bpbuf, ps);
- binpath_G = bpbuf;
- }
- else
- binpath_G = BINDIR;
- }
- if (binpath_G && lastchar (binpath_G) == SLASH_CHR)/* rem trail '/' */
- lastchar (binpath_G) = '\0';
- dbg(("binpath_G = |%s|\n", binpath_G ? binpath_G : "NULL"));
-
-
-
- /*
- * finally, deal with MANSECT. this should be last section
- * since this returns.
- */
- if ((ps = getenv ("MANSECT")) != (char *) NULL)
- {
- strcpy (sectbuf, ps);
- dbg(("MANSECT = |%s|\n", sectbuf));
- envmansect_G = 1;
-
- pl = ps = sectbuf;
- while (*ps && *ps != ',') /* find first , */
- ps++;
- if (*ps == '\0') /* if no more list, return */
- return;
- *ps++ = '\0'; /* terminate allsect */
-
- allsect = pl;
- dbg(("allsect = |%s|\n", allsect));
-
- while (*pl)
- {
- dbg(("for sect %c, ", (int) *pl));
- pd = ps;
- switch (*pl)
- {
- case '0': subsec0 = ps; goto find_comma;
- case '1': subsec1 = ps; goto find_comma;
- case '2': subsec2 = ps; goto find_comma;
- case '3': subsec3 = ps; goto find_comma;
- case '4': subsec4 = ps; goto find_comma;
- case '5': subsec5 = ps; goto find_comma;
- case '6': subsec6 = ps; goto find_comma;
- case '7': subsec7 = ps; goto find_comma;
- case '8': subsec8 = ps; goto find_comma;
- case '9': subsec9 = ps;
- find_comma: ;
- if (*ps == ',')
- {
- *ps++ = '\0';
- if (*ps == '\0')
- {
- dbg(("subsec = empty\n"));
- return;
- }
- dbg(("subsec = empty\n"));
- break;
- }
- while (*ps && *ps != ',')
- ps++;
- if (*ps == '\0')
- {
- dbg(("subsec = empty\n"));
- return;
- }
- *ps++ = '\0';
- dbg(("subsec = |%s|\n", pd));
- break;
-
- default:
- break;
- }
- pl++;
- }
- }
- }
-
-
- #define FP fprintf
-
- /*------------------------------*/
- /* usage */
- /*------------------------------*/
- void usage (int excode)
- {
- char *ps;
- int i;
-
- #if 0
- FP (stderr, "Usage: %s [-s sec[sub]] [-M dir | -m dir] [- [-ul]] [-k key] [-f file] [sec[sub]] name\n", myname);
- #endif
-
-
- FP (stderr, "\nUsage: %s [options] [sec[sub]] name\n", myname);
-
-
- FP (stderr, "Opts: -s sec[sub] section/subsect (e.g. 2g)\n");
- FP (stderr, " -M dir specify search dir (for man tree)\n");
- FP (stderr, " -m dir specify search dir (dir, no tree, eg man -m .)\n");
- #ifdef HAS_CAT
- FP (stderr, " - use cat rather than more or less\n");
- # ifdef HAS_UL
- FP (stderr, " - -ul use ul rather than cat\n");
- # endif
- #endif
- #ifdef HAS_APROPOS
- FP (stderr, " -k key same as \"apropos keyword\"\n");
- #endif
- #ifdef HAS_WHATIS
- FP (stderr, " -f file same as \"whatis file\"\n");
- #endif
-
-
- FP (stderr, "Args: sec section, alternate for -s\n");
- FP (stderr, " sub subsection, alternate for -s\n");
- FP (stderr, " name desired entry (command, etc)\n");
-
-
- FP (stderr, "Search order:\n");
- if (envmansect_G)
- {
- for (ps = allsect; *ps; ps++)
- {
- switch (*ps)
- {
- case '0':
- FP (stderr, " %s0%s*.0", SUBDIRBASE, SLASH_STR);
- if (*subsec0)
- FP (stderr, "[%s]%s", subsec0, (strlen(subsec0) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "general\n");
- break;
- case '1':
- FP (stderr, " %s1%s*.1", SUBDIRBASE, SLASH_STR);
- if (*subsec1)
- FP (stderr, "[%s]%s", subsec1, (strlen(subsec1) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "commands\n");
- break;
- case '2':
- FP (stderr, " %s2%s*.2", SUBDIRBASE, SLASH_STR);
- if (*subsec2)
- FP (stderr, "[%s]%s", subsec2, (strlen(subsec2) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "system calls\n");
- break;
- case '3':
- FP (stderr, " %s3%s*.3", SUBDIRBASE, SLASH_STR);
- if (*subsec3)
- FP (stderr, "[%s]%s", subsec3, (strlen(subsec3) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "library calls\n");
- break;
- case '4':
- FP (stderr, " %s4%s*.4", SUBDIRBASE, SLASH_STR);
- if (*subsec4)
- FP (stderr, "[%s]%s", subsec4, (strlen(subsec4) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "hardware\n");
- break;
- case '5':
- FP (stderr, " %s5%s*.5", SUBDIRBASE, SLASH_STR);
- if (*subsec5)
- FP (stderr, "[%s]%s", subsec5, (strlen(subsec5) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "special files\n");
- break;
- case '6':
- FP (stderr, " %s6%s*.6", SUBDIRBASE, SLASH_STR);
- if (*subsec6)
- FP (stderr, "[%s]%s", subsec6, (strlen(subsec6) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "games\n");
- break;
- case '7':
- FP (stderr, " %s7%s*.7", SUBDIRBASE, SLASH_STR);
- if (*subsec7)
- FP (stderr, "[%s]%s", subsec7, (strlen(subsec7) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "misc\n");
- break;
- case '8':
- FP (stderr, " %s8%s*.8", SUBDIRBASE, SLASH_STR);
- if (*subsec8)
- FP (stderr, "[%s]%s", subsec8, (strlen(subsec8) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "admin commands\n");
- break;
- case '9':
- FP (stderr, " %s9%s*.9", SUBDIRBASE, SLASH_STR);
- if (*subsec9)
- FP (stderr, "[%s]%s", subsec9, (strlen(subsec9) < 7) ? "\t " : " ");
- else
- FP (stderr, "\t\t ");
- FP (stderr, "other\n");
- break;
- }
- }
- }
- else
- {
- FP (stderr, " %s1%s*.1[tcgesla] cmds (util & text,com,graph,edit,shell,lang,archive)\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s0%s*.0 general\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s8%s*.8[s] admin (util & system)\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s2%s*.2[b] syslib (unix & bios)\n", SUBDIRBASE,SLASH_STR);
- FP (stderr, " %s3%s*.3[msvcxl] libs (C lib & math,stdio,sysV,compat,misc,local)\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s4%s*.4[dkvscm] h/w (gen & disk,keyboard,video,sound,chips,memory)\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s5%s*.5 special files\n", SUBDIRBASE,SLASH_STR);
- FP (stderr, " %s7%s*.7 misc\n", SUBDIRBASE, SLASH_STR);
- FP (stderr, " %s6%s*.6 games\n", SUBDIRBASE, SLASH_STR);
- }
-
-
- #ifdef LONG_SECT
- FP (stderr, "Other sections: ");
- for (i = 0; i < 10; i++)
- {
- if (longsect[i] == (char *) NULL)
- break;
- FP (stderr, "%s", longsect[i]);
- if (longsect[i+1])
- FP (stderr, ",");
- }
- FP (stderr, "\n");
- #else
- FP (stderr, "Other sections: local,new,old\n");
- #endif
-
-
- FP (stderr, "Environment: MANPAGER,PAGER,MANPATH,MANSECT,BINDIR,TMPDIR\n");
-
-
- exit (excode);
- }
-
-
-